package com.exam.service.Impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.exam.annotation.Cache;
import com.exam.entity.Notice;
import com.exam.exception.BusinessException;
import com.exam.exception.CommonErrorCode;
import com.exam.mapper.NoticeMapper;
import com.exam.service.NoticeService;
import com.exam.utils.CommonUtils;
import com.exam.utils.RedisUtil;
import com.exam.vo.PageResponse;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.Collections;
import java.util.Date;
import java.util.concurrent.TimeUnit;

/**
 * @Author 小聋包
 * @Date 2024/4/16 10:27
 * @Version 1.0
 */
@Service
@RequiredArgsConstructor
public class NoticeServiceImpl extends ServiceImpl<NoticeMapper, Notice> implements NoticeService {
    private final NoticeMapper noticeMapper;

    private final RedisUtil redisUtil;
    /**
     * 获取所有公告
     * @param content
     * @param pageNo
     * @param pageSize
     * @return
     */
    @Override
    public PageResponse<Notice> getAllNotices(String content, Integer pageNo, Integer pageSize) {
        IPage<Notice> noticeIPage=new Page<>(pageNo,pageSize);
        QueryWrapper<Notice> wrapper=new QueryWrapper<>();
        CommonUtils.setLikeWrapper(wrapper, Collections.singletonMap("content",content));
        noticeIPage=noticeMapper.selectPage(noticeIPage,wrapper);

        return PageResponse.<Notice>builder()
                .data(noticeIPage.getRecords())
                .total(noticeIPage.getTotal())
                .build();
    }


    @Override
    public boolean setAllNoticeIsHistoryNotice() {
        return noticeMapper.setAllNoticeIsHistoryNotice();
    }
    /**
     * 发布新公告
     * @param notice
     */
    @Override
    public void publishNotice(Notice notice) {
        if (notice.getStatus() == 1) {//  当前发布的是置顶公告
            //  1. 将当前所有公告设置为历史公告
            setAllNoticeIsHistoryNotice();
            //  2. 新增最新公告进去
            notice.setCreateTime(new Date());
            boolean save = noticeMapper.insert(notice) > 0;
            if (redisUtil.get("currentNewNotice") != null && save) {
                redisUtil.set("currentNewNotice", notice.getContent());
            }
        } else if (notice.getStatus() == 0) {//  不发布最新公告
            notice.setCreateTime(new Date());
            noticeMapper.insert(notice);
        } else {
            throw new BusinessException(CommonErrorCode.E_300001);
        }
    }

    /**
     * 批量删除公告
     * @param noticeIds 要删除的公告ID列表
     */
    @Override
    public void deleteNoticeByIds(String noticeIds) {
        // 将传入的公告ID列表字符串按逗号分割成数组
        //转换成数组 需要操作的用户id数组
        String [] ids = noticeIds.split(",");

        // 查询当前状态为置顶的公告
        Notice currentNotice = noticeMapper.selectOne(new QueryWrapper<Notice>().eq("status", "1"));

        // 遍历需要删除的公告ID数组
        for (String id : ids) {
            // 如果当前置顶的公告ID与要删除的公告ID相同，则跳过该ID，不执行删除操作
            if (currentNotice.getNId().equals(Integer.parseInt(id))) {
                continue;
            }

            // 删除指定ID的公告
            noticeMapper.deleteById(Integer.parseInt(id));
        }
    }



    /**
     * 更新公告
     * @param notice
     */
    @Override
    public void updateNotice(Notice notice) {
        //查询当前公告信息
        QueryWrapper<Notice> wrapper = new QueryWrapper<Notice>().eq("n_id", notice.getNId());
        Notice targetNotice=noticeMapper.selectOne(wrapper);

        if (notice.getStatus() == 1) {
            // 当前发布的是置顶公告
            //  1. 将当前所有公告设置为历史公告
            setAllNoticeIsHistoryNotice();
            // 更新目标公告的更新时间和内容
            targetNotice.setUpdateTime(new Date());
            targetNotice.setContent(notice.getContent());
            targetNotice.setStatus(notice.getStatus());

            // 更新目标公告
            boolean update = noticeMapper.update(targetNotice,wrapper) > 0;
            // 如果缓存中存在当前公告并且更新成功，则更新缓存
            if (redisUtil.get("currentNewNotice") != null && update) {
                redisUtil.set("currentNewNotice", notice.getContent());
            }
        } else if (notice.getStatus() == 0) {
            // 不发布最新公告
            // 更新目标公告的更新时间和内容
            targetNotice.setUpdateTime(new Date());
            targetNotice.setContent(notice.getContent());
            targetNotice.setStatus(notice.getStatus());
            // 更新目标公告
            noticeMapper.update(targetNotice,wrapper);
        } else {
            // 其他状态为非法状态，抛出业务异常
            throw new BusinessException(CommonErrorCode.E_300002);
        }
    }

    /**
     * 获取当前系统最新的公告
     *
     * @return 返回公告的内容
     */
    // 使用Cache注解，缓存前缀为"currentNewNotice"，缓存时间为10小时，随机时间范围为2小时，时间单位为小时
    @Cache(prefix = "currentNewNotice", ttl = 10, randomTime = 2, timeUnit = TimeUnit.HOURS)
    @Override
    public String getCurrentNotice() {
        // 调用noticeMapper的selectOne方法，使用QueryWrapper条件构造器筛选出状态为"1"的公告
        // 返回公告的内容
        return noticeMapper.selectOne(new QueryWrapper<Notice>().eq("status", "1")).getContent();
    }

}
